package com.easylinkin.linkappapi.operatelog;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import com.easylinkin.linkappapi.common.utils.async.SpringUtils;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import site.morn.translate.Translator;

/**
 * 日志帮助类，在Controller中设置日志的content, 操作成功后OperationRecordAspec会记录成功日志
 * 
 * @author OYGD
 *
 */
@Slf4j
public class LogHelper {

  private static Translator translator;

  private LogHelper() {}

  private static final ThreadLocal<String> logContentThreadLocal = new ThreadLocal<>();
  private static final ThreadLocal<String> logModelIdThreadLocal = new ThreadLocal<>();
  private static final ThreadLocal<LinkappUser> customerThreadLocal = new ThreadLocal<>();

  public static String getContent() {
    return logContentThreadLocal.get();
  }

  public static void setContent(String content, Object... args) {
    if (null == translator) {
      translator = SpringUtils.getBean(Translator.class);
    }
    String message = translator.translate(content, args, content);
    logContentThreadLocal.set(message);
  }

  public static String getModelId() {
    return logModelIdThreadLocal.get();
  }

  public static void setModelId(String modelId) {
    logModelIdThreadLocal.set(modelId);
  }

  public static LinkappUser getCustomer() {
    return customerThreadLocal.get();
  }

  public static void setCustomer(LinkappUser customer) {
    customerThreadLocal.set(customer);
  }

  public static void clearContent() {
    logContentThreadLocal.remove();
    logModelIdThreadLocal.remove();
    customerThreadLocal.remove();
  }
  public static String beanToLog(Object obj) {
    return beanToLog(obj, true);
  }

  public static String beanToLog(Object obj, boolean ignoreNull) {
    StringBuilder sb = new StringBuilder();
    try {
      if (null != obj) {
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
          LogField f = field.getAnnotation(LogField.class);
          if (f == null) {
            continue;
          }
          String prefix = "get";
          if (field.getType() == boolean.class) {
            prefix = "is";
          }
          String methodName = prefix + StringUtils.capitalize(field.getName());
          Method method = ReflectUtil.getMethod(obj.getClass(), methodName);
          if (method == null) {
            continue;
          }
          Object value = ReflectUtil.invoke(obj, method);
          if (ignoreNull && value == null) {
            continue;
          }
          if (value instanceof Date) {
            value = DateUtil.formatDateTime((Date)value);
          }
          if (sb.length() > 0) {
            sb.append(", ");
          }
          sb.append(f.name()).append(":").append(value);
        }
      }
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }
    return sb.toString();
  }
}
